/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


package cartagows;

import java.util.Iterator;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAPHeader;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.HandlerDescription;
import org.apache.axis2.engine.AbstractDispatcher;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.i18n.Messages;
import org.apache.axis2.util.LoggingControl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Axis2TransportDispatcher extends AbstractDispatcher {

    public static final String NAME = "Axis2TransportDispatcher";
    private static final Log log = LogFactory.getLog(Axis2TransportDispatcher.class);
    public static final String PROXY_PREFIX ="Proxy:";
    
    // TODO this logic needed to be improved, as the Dispatching is almost guaranteed to fail
    public AxisOperation findOperation(AxisService service, MessageContext messageContext)
            throws AxisFault {
        AxisOperation op = service.getOperationByAction("notifyMsg");
        return op;
    }

    public AxisService findService(MessageContext messageContext) throws AxisFault {
    	log.info("FIND SERVICE: "+messageContext);
        EndpointReference toEPR = messageContext.getTo();

    	//log.info("> ENDP "+toEPR.toString());
        
        if ((toEPR == null) || (toEPR.hasAnonymousAddress())) {
            return null;
        }

        AxisService service = null;
        String fullAddress = toEPR.getAddress();
        
        //log.info("Full service address: "+fullAddress);
        int index = fullAddress.lastIndexOf("/");
        String lastPart = fullAddress.substring(index+1);
        
        String address = null;
        if (lastPart.startsWith(PROXY_PREFIX)){
        	/* 
        	 * the target is a proxy artifact...
        	 * 
        	 * the address is of the kind:
        	 * http://acme.org/../ServiceName/ProxyArtifactName
        	 */ 
        	// getting what Axis2 sees as ENDP: http://acme.org/../ServiceName 
        	//log.info("this is a proxy");
        	address = fullAddress.substring(0,index);
        } else {
        	/*
        	 * It's a service.
        	 */
        	//log.info("this is a service");
        	address = fullAddress;
        }
        //log.info("Service address resolved: "+address);
        
        if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled()) {
            log.debug(messageContext.getLogIDString() + " " +
                    Messages.getMessage("checkingserviceforepr", address));
        }

        ConfigurationContext configurationContext = messageContext.getConfigurationContext();

        AxisConfiguration registry =
            configurationContext.getAxisConfiguration();

        service = registry.getService("cartagows");

        /*
        ConfigurationContext configurationContext = messageContext.getConfigurationContext();
        String[] values = Utils.parseRequestURLForServiceAndOperation(address,configurationContext.getServiceContextPath());

        if (values == null) {
            return null;
        }

        if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled()) {
            log.debug(messageContext.getLogIDString() + " " +
                    Messages.getMessage("checkingserviceforepr", values[0]));
        }

        if (values[0] != null) {
            AxisConfiguration registry =
                    configurationContext.getAxisConfiguration();

            service = registry.getService(values[0]);

            // If the axisService is not null we get the binding that the request came to and
            // add it as a property to the messageContext
            if (service != null) {
                Map endpoints = service.getEndpoints();
                if (endpoints != null) {
                    if (endpoints.size() == 1) {
                        messageContext.setProperty(WSDL2Constants.ENDPOINT_LOCAL_NAME,
                                                   endpoints.get(
                                                           service.getEndpointName()));
                    } else {
                        String endpointName = values[0].substring(values[0].indexOf(".") + 1);
                        messageContext.setProperty(WSDL2Constants.ENDPOINT_LOCAL_NAME,
                                                   endpoints.get(endpointName));
                    }
                }
            }
        }*/
        //log.info("found service: "+service);
        return service;
    }

    public void initDispatcher() {
        init(new HandlerDescription(NAME));
    }
    
	public OMElement getHeaderElement(SOAPHeader header, String localName){
		Iterator<OMElement> it = header.getChildElements();
		while (it.hasNext()){
			OMElement el = it.next();
			//log.info("NODE: "+el.getLocalName());
			if (el.getLocalName().equals(localName)){
				return el;
			}
		}
		return null;
	}
}